module Main exposing (..)

import Html exposing (Html, a, button, code, div, h1, li, text, ul)
import Html.Attributes exposing (href,style)
import Navigation
import UrlParser as Url exposing ((</>), (<?>), s, int, stringParam, top)
import Login
import Nodes
import Article


main : Program Never Model Msg
main =
  Navigation.program UrlChange
    { init = init
    , view = view
    , update = update
    , subscriptions = subscriptions
    }



type alias Model =
  { route : Route
  , login : Login.Model
  , nodes : Nodes.Model
  , article : Article.Model
  }


init : Navigation.Location -> ( Model, Cmd Msg )
init location =
  ( Model Login Login.initModel Nodes.initModel Article.initModel
  , Cmd.none
  )


type Route
  = Home
  | Login
  | NodesPage Int
  | ArticlePage Int


parser : Url.Parser (Route -> a) a
parser =
  Url.oneOf
    [ Url.map Home top
    , Url.map Login (s "login")
    , Url.map NodesPage (s "nodes" </> int)
    , Url.map ArticlePage (s "article" </> int) ]



type Msg
  = UrlChange Navigation.Location
  | LoginMsg Login.Msg
  | NodesMsg Nodes.Msg
  | ArticleMsg Article.Msg


-- 触发各自的routeChange事件
refresh : Route -> Model -> (Model,Cmd Msg)
refresh newRoute model =
 let 
  changed = newRoute /= model.route
 in 
  case newRoute of
   Home -> (model,Cmd.none)

   Login ->  (model,Cmd.none)

   NodesPage id -> 
    case changed of
     True ->
      let
       (newNodes,cmd) = Nodes.refresh id model.nodes
      in 
       ({model | nodes = newNodes},Cmd.map NodesMsg cmd)
     False -> (model,Cmd.none)

   ArticlePage id ->
    case changed of
     True ->
      let
       (newArticle,cmd) = Article.refresh id model.article
      in 
       ({model | article = newArticle},Cmd.map ArticleMsg cmd)
     False -> (model,Cmd.none)

   
reset : Model -> (Model,Cmd Msg)
reset model =
 case model.route of
  Home -> (model,Cmd.none)
  Login -> (model,Cmd.none)
  NodesPage id -> ( {model | nodes = Nodes.reset id model.nodes },Cmd.none)
  ArticlePage id -> ( {model | article = Article.reset id model.article },Cmd.none)


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
  case msg of
    UrlChange location ->
     let
      route = Maybe.withDefault Home (Url.parseHash parser location)
      (newModel,cmd) = refresh route model
     in ( {newModel | route = route } , cmd)
    -- UrlChange location ->
    --  let
    --   route = Maybe.withDefault Home (Url.parseHash parser location)
    --   modelWithNewRoute = {model | route = route }
    --  in
    --   reset modelWithNewRoute
    
    LoginMsg subMsg -> 
     let
      (loginModel,cmd) = Login.update subMsg model.login
     in ({model | login = loginModel},Cmd.map LoginMsg cmd)

    NodesMsg subMsg -> 
     let
      (newNodes,cmd) = Nodes.update subMsg model.nodes
     in ({model | nodes = newNodes},Cmd.map NodesMsg cmd)

    ArticleMsg subMsg ->
     let
      (newArticle,cmd) = Article.update subMsg model.article
     in ({model | article = newArticle},Cmd.map ArticleMsg cmd)


subscriptions : Model -> Sub Msg
subscriptions model =
  Sub.none

margin : Int -> Int -> Int -> Int -> Html.Attribute msg
margin u r d l = style [("margin",String.join "px " [toString u,toString r,toString d,toString l] ++ "px" )]


nav : Html Msg
nav = 
 div [margin 0 0 10 0]
  [ a [href "#/nodes/0", margin 0 10 0 0] [text "主列表"]
  , a [href "#/login"] [text "登陆"] ]
 



view : Model -> Html Msg
view model =
 let routeView = case model.route of
   Home -> Html.map LoginMsg (Login.view model.login)
   Login -> Html.map LoginMsg (Login.view model.login)
   NodesPage id -> Html.map NodesMsg (Nodes.view model.nodes)
   ArticlePage id -> Html.map ArticleMsg (Article.view model.article)
 in
  div []
   [ nav
   , routeView]